#!/usr/bin/python
# -*- coding: UTF-8 -*-
'''
STM32工程编译控制脚本
'''
import os
import xml.etree.ElementTree as ET


class Project(object):
    '''
    工程对应操作类
    '''

    def __init__(self, xmlfile):
        xmldoc = ET.parse(xmlfile)
        root = xmldoc.getroot()
        self.name = root.find("name").text
        self.basepath = root.find("basepath").text
        self.ObjOutPath =self.basepath + root.find("ObjOutPath").text
        self.BinOutPath =self.basepath + root.find("BinOutPath").text
        self.TargetFile = self.BinOutPath + self.name + ".elf"
        if root.find("buildSpec/buildoption/createhex").text == "True":
            self.IsCreateHex = True
        else:
            self.IsCreateHex = False
        self.ToolChainPath = root.find('buildSpec/ToolChain/binpath').text
        self.CC = self.ToolChainPath + root.find('buildSpec/ToolChain/CC').text
        self.AS = self.ToolChainPath + root.find('buildSpec/ToolChain/AS').text
        self.LD = self.ToolChainPath + root.find('buildSpec/ToolChain/LD').text
        self.OBJCOPY = self.ToolChainPath + root.find('buildSpec/ToolChain/OBJCOPY').text
        self.CFLAGS = ""
        for cflags in root.findall('buildSpec/buildargs/CFLAGS'):
            self.CFLAGS += " " + cflags.text
        for inc in root.findall('buildSpec/buildargs/include'):
            self.CFLAGS += ' -I ' + self.basepath + inc.text
        self.ASFLAGS = ""
        for asflags in root.findall('buildSpec/buildargs/ASFLAGS'):
            self.ASFLAGS += " " + asflags.text
        self.LDFLAGS = ""
        for ldflags in root.findall('buildSpec/buildargs/LDFLAGS'):
            self.LDFLAGS += " " + ldflags.text
        self.LDFLAGS += " -T " + self.basepath + root.find('buildSpec/buildargs/LDFILE').text

        self.cfile = []
        self.asmfile = []
        for _file in root.findall("sourcefile/dir/file"):
            if _file.get("ext") == "c":
                self.cfile.append(self.basepath + _file.text)
            elif _file.get("ext") == "s":
                self.asmfile.append(self.basepath + _file.text)

    def GetOutFile(self,infile):
        return self.ObjOutPath + os.path.basename(infile).split(".")[0] + ".o"

    def CompileC(self,infile):
        outfile = self.GetOutFile(infile)
        if  os.path.exists(outfile) and os.path.getmtime(outfile) > os.path.getmtime(infile):
            return
        print("Compiling: " + infile)
        os.system(self.CC + " " + self.CFLAGS + " -c -o " + outfile + " " + infile)

    def CompileAsm(self,infile):
        outfile = self.GetOutFile(infile)
        if  os.path.exists(outfile) and os.path.getmtime(outfile) > os.path.getmtime(infile):
            return
        print("Compiling: " + infile)
        os.system(self.CC + " " + self.ASFLAGS + " -c -o " + outfile + " " + infile)

    def CompileAll(self):
        for _file in self.asmfile:
            self.CompileAsm(_file)
        for _file in self.cfile:
            self.CompileC(_file)

    def Link(self):
        objfile = []
        for _file in self.asmfile:
            objfile.append(self.GetOutFile(_file))
        for _file in self.cfile:
            objfile.append(self.GetOutFile(_file))
        if os.path.exists(self.TargetFile):#判断是否需要更新
            IsLastest = True
            for _file in objfile:
                if os.path.getmtime(_file)>os.path.getmtime(self.TargetFile):
                    IsLastest = False
            if IsLastest:
                print("已是最新，未进行任何操作")
                return
        objstr = ""
        for _file in objfile:
            objstr += " " + _file
        print("Linking...")
        os.system(self.CC + self.LDFLAGS + " -o " + self.TargetFile + objstr)
        if self.IsCreateHex:
            os.system(self.OBJCOPY + " " + self.TargetFile + " " + self.BinOutPath + self.name + ".hex -Oihex")
            os.system(self.OBJCOPY + " " + self.TargetFile + " " + self.BinOutPath + self.name + ".bin -Obinary")

if __name__ == "__main__":
    if not os.path.exists("project.xml"):
        print("cannot find project.xml")
        exit()
    project = Project("project.xml")
    project.CompileAll()
    project.Link()
